/*******************************************************************************
 * Copyright (c) 2011 Prometheus Consulting
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
/**
 * 
 */
package nz.co.senanque.vaadinsupport.formatting;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;

import nz.co.senanque.vaadinsupport.hibernatecontainer.HbnContainerTransactional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.MessageSourceAccessor;

import com.vaadin.data.Container;
import com.vaadin.data.Property;
import com.vaadin.data.util.ContainerOrderedWrapper;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.event.Action;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.ui.Component;
import com.vaadin.ui.Table;

/**
 * Extension of the Vaadin table to recognise numeric types and adjust formatting to locale-specific and right justify.
 * Also supports locale driven headings and column selection.
 * 
 * Call setContainerDataSource with the extra parameters.
 * 
 * @author Roger Parkinson
 * 
 */
public class FormattingTable extends Table {

	private static final long serialVersionUID = 7237968007631681880L;
	
	private Object[] visiblePropertyIds=null;
	private String[] headings_ = null;
	private Container m_deferredContainer;
	private boolean m_initializing = true;
    private static Logger log = LoggerFactory.getLogger(FormattingTable.class);


	protected String formatPropertyValue(Object rowId, Object colId,
			Property property) {
		// Format by property type
		Formatter formatter = FormatterFactory.getFormatter(property.getType());
		if (formatter != null) {
			// setColumnAlignment(colId, Table.ALIGN_RIGHT);
			return formatter.format(property.getValue());
		}
		return super.formatPropertyValue(rowId, colId, property);
	}

	/**
	 * Does the same as the normal setContainerDataSource but accepts the column list (subset) and the headings for each column.
	 * The headings are translated to the current locale.
	 * Column names for numeric values should be prefixed with '-' which will make the right justify.
	 * Numbers (Double, Float, Long, Integer, BigDecimal) will be formatted for the current locale.
	 * @param indexed
	 * @param allColumns
	 * @param headings
	 * @param messageSourceAccessor 
	 */
	public void setContainerDataSource(Container indexed, String[] allColumns, String[] headings, MessageSourceAccessor messageSourceAccessor) {
		boolean contentRefreshing = super.disableContentRefreshing();
		Collection<?> propertyIds = indexed.getContainerPropertyIds();
		m_deferredContainer = indexed;
		visiblePropertyIds = new String[allColumns.length];
		headings_ = new String[allColumns.length];
		int i = 0;
		for (int j = 0; j < allColumns.length; j++) {
			for (Object propertyId : propertyIds) {
				String thisColumn = allColumns[j];
				if (thisColumn.startsWith("-"))
				{
					thisColumn = thisColumn.substring(1);
					setColumnAlignment(thisColumn, Table.ALIGN_RIGHT);
				}
				if (propertyId.toString().equals(thisColumn)) {
					visiblePropertyIds[i] = propertyId;
					headings_[i] = messageSourceAccessor.getMessage(headings[j]);
					i++;
					break;
				}
			}
		}
	}
    @Override
    public void attach() {
        log.debug("attach()");
        super.attach();

		super.setContainerDataSource(m_deferredContainer);
		super.disableContentRefreshing(); // again
		super.setVisibleColumns(visiblePropertyIds);
		super.setColumnHeaders(headings_);
		super.enableContentRefreshing(true);
		m_initializing = false;

    }
    protected void refreshRenderedCells() {
        if (getParent() == null) {
            return;
        }
        if (m_initializing)
        {
        	return;
        }
        log.debug("refreshRenderedCells()");
        super.refreshRenderedCells();
    }
    @Override
    public void paintContent(PaintTarget target) throws PaintException {
        if (m_initializing)
        {
        	return;
        }
        log.debug("paintContent({})",target);
    	super.paintContent(target);
    }
    protected void enableContentRefreshing(boolean refreshContent) {
        if (m_initializing)
        {
        	return;
        }
        log.debug("enableContentRefreshing({})",refreshContent);
        super.enableContentRefreshing(true);
    }
}
